In [ ]:
import pandas as pd
import numpy as np
symbol = 'Security 1'
symbol2 = 'Security 2'
In [ ]:
price_data = pd.DataFrame(np.cumsum(np.random.randn(150, 2).dot([[0.5, 0.4], [0.4, 1.0]]), axis=0) + 100,
columns=['Security 1', 'Security 2'],
index=pd.date_range(start='01-01-2007', periods=150))
dates_actual = price_data.index.values
prices = price_data[symbol].values
In [ ]:
from bqplot import (DateScale, LinearScale, Axis, Lines, Scatter, Bars, Hist, Figure)
from bqplot.interacts import (FastIntervalSelector, IndexSelector, BrushIntervalSelector,
BrushSelector, MultiSelector, LassoSelector, PanZoom, HandDraw)
from traitlets import link
from IPython.display import display
from ipywidgets import Label, ToggleButtons, VBox
In [ ]:
## First we define a Figure
dt_x_fast = DateScale()
lin_y = LinearScale()
x_ax = Axis(label="Index", scale=dt_x_fast)
x_ay = Axis(label=(symbol + " Price"), scale=lin_y, orientation="vertical", tick_format="0.2f")
lc = Lines(x=dates_actual, y=prices, scales={'x': dt_x_fast, 'y': lin_y}, colors=['orange'])
lc_2 = Lines(x=dates_actual[50:], y=prices[50:] + 2, scales={'x': dt_x_fast, 'y': lin_y}, colors=['blue'])
In [ ]:
## Next we define the type of selector we would like
intsel_fast = FastIntervalSelector(scale=dt_x_fast, marks=[lc, lc_2])
In [ ]:
## Now, we define a function that will be called when the FastIntervalSelector is interacted with
def fast_interval_change_callback(change):
db_fast.value = 'The selected period is ' + str(change['new'])
In [ ]:
## Now we connect the selectors to that function
intsel_fast.observe(fast_interval_change_callback, names=['selected'])
In [ ]:
## We use the Label widget to see the value of what we are selecting and modify it when an interaction is performed
## on the selector
db_fast = Label(color='Black', font_size='24px')
db_fast.value = str(intsel_fast.selected)
display(db_fast)
fig_fast_intsel = Figure(marks=[lc, lc_2], axes=[x_ax, x_ay], title="Fast Interval Selector Example",
interaction=intsel_fast) #This is where we assign the interaction to this particular Figure
display(fig_fast_intsel)
In [ ]:
db_index = Label(color='Black', font_size='24px', value='[]')
In [ ]:
## Now we try a selector made to select all the y-values associated with a single x-value
index_sel = IndexSelector(scale=dt_x_fast, marks=[lc, lc_2])
In [ ]:
## Now, we define a function that will be called when the selectors are interacted with
def index_change_callback(change):
db_index.value = 'The selected date is ' + str(change['new'])
In [ ]:
index_sel.observe(index_change_callback, names=['selected'])
In [ ]:
fig_index_sel = Figure(marks=[lc, lc_2], axes=[x_ax, x_ay], title="Index Selector Example",
interaction=index_sel)
display(db_index)
display(fig_index_sel)
In [ ]:
from datetime import datetime as py_dtime
dt_x_index = DateScale(min=np.datetime64(py_dtime(2006, 6, 1)))
lin_y2 = LinearScale()
lc2_index = Lines(x=dates_actual, y=prices,
scales={'x': dt_x_index, 'y': lin_y2})
x_ax1 = Axis(label="Date", scale=dt_x_index)
x_ay2 = Axis(label=(symbol + " Price"), scale=lin_y2, orientation="vertical", tick_format="0.2f")
In [ ]:
intsel_date = FastIntervalSelector(scale=dt_x_index, marks=[lc2_index])
In [ ]:
db_date = Label(color='Black', font_size='24px')
db_date.value = str(intsel_date.selected)
In [ ]:
## Now, we define a function that will be called when the selectors are interacted with - a callback
def date_interval_change_callback(change):
db_date.value = str(change['new'])
In [ ]:
## Notice here that we call the observe on the Mark lc2_index rather than on the selector intsel_date
lc2_index.observe(date_interval_change_callback, names=['selected'])
fig_date_mark = Figure(marks=[lc2_index], axes=[x_ax1, x_ay2],
title='Fast Interval Selector Selected Indices Example', interaction=intsel_date)
display(db_date)
display(fig_date_mark)
In [ ]:
## Defining a new Figure
dt_x_brush = DateScale(min=np.datetime64(py_dtime(2006, 6, 1)))
lin_y2_brush = LinearScale()
lc3_brush = Lines(x=dates_actual, y=prices,
scales={'x': dt_x_brush, 'y': lin_y2_brush})
x_ax_brush = Axis(label="Date", scale=dt_x_brush)
x_ay_brush = Axis(label=(symbol + " Price"), scale=lin_y2_brush, orientation="vertical", tick_format="0.2f")
In [ ]:
db_brush = Label(color='Black', font_size='24px', value='[]')
In [ ]:
brushsel_date = BrushIntervalSelector(scale=dt_x_brush, marks=[lc3_brush], color='FireBrick')
In [ ]:
## Now, we define a function that will be called when the selectors are interacted with - a callback
def date_brush_change_callback(change):
db_brush.value = str(change['new'])
In [ ]:
lc3_brush.observe(date_brush_change_callback, names=['selected'])
In [ ]:
fig_brush_sel = Figure(marks=[lc3_brush], axes=[x_ax_brush, x_ay_brush],
title="Brush Selector Selected Indices Example", interaction=brushsel_date)
display(db_brush)
display(fig_brush_sel)
In [ ]:
date_fmt = '%m-%d-%Y'
sec2_data = price_data[symbol2].values
dates = price_data.index.values
In [ ]:
sc_x = LinearScale()
sc_y = LinearScale()
scatt = Scatter(x=prices, y=sec2_data,
scales={'x': sc_x, 'y': sc_y})
sc_xax = Axis(label=(symbol), scale=sc_x, tick_format="0.0f")
sc_yax = Axis(label=(symbol2), scale=sc_y, orientation="vertical", tick_format="0.0f")
In [ ]:
br_sel = BrushSelector(x_scale=sc_x, y_scale=sc_y, marks=[scatt], color='red')
db_scat_brush = Label(color='Black', font_size='24px', value='[]')
In [ ]:
## call back for the selector
def brush_callback(change):
db_scat_brush.value = str(br_sel.selected)
In [ ]:
br_sel.observe(brush_callback, names=['brushing'])
In [ ]:
fig_scat_brush = Figure(marks=[scatt], axes=[sc_xax, sc_yax], title='Scatter Chart Brush Selector Example',
interaction=br_sel)
In [ ]:
display(db_scat_brush)
display(fig_scat_brush)
In [ ]:
sc_brush_dt_x = DateScale(date_format=date_fmt)
sc_brush_dt_y = LinearScale()
scatt2 = Scatter(x=dates_actual, y=sec2_data,
scales={'x': sc_brush_dt_x, 'y': sc_brush_dt_y})
In [ ]:
br_sel_dt = BrushSelector(x_scale=sc_brush_dt_x, y_scale=sc_brush_dt_y, marks=[scatt2])
In [ ]:
db_brush_dt = Label(color='Black', font_size='24px')
db_brush_dt.value = str(br_sel_dt.selected)
In [ ]:
## call back for the selector
def brush_dt_callback(change):
db_brush_dt.value = str(br_sel_dt.selected)
In [ ]:
br_sel_dt.observe(brush_callback, names=['brushing'])
In [ ]:
sc_xax = Axis(label=(symbol), scale=sc_brush_dt_x)
sc_yax = Axis(label=(symbol2), scale=sc_brush_dt_y, orientation="vertical", tick_format="0.0f")
fig_brush_dt = Figure(marks =[scatt2], axes=[sc_xax, sc_yax], title='Brush Selector with Dates Example',
interaction=br_sel_dt)
In [ ]:
display(db_brush_dt)
display(fig_brush_dt)
In [ ]:
## call back for selectors
def interval_change_callback(name, value):
db3.value = str(value)
## call back for the selector
def brush_callback(change):
if(not br_intsel.brushing):
db3.value = str(br_intsel.selected)
In [ ]:
returns = np.log(prices[1:]) - np.log(prices[:-1])
hist_x = LinearScale()
hist_y = LinearScale()
hist = Hist(sample=returns, scales={'sample': hist_x, 'count': hist_y})
br_intsel = BrushIntervalSelector(scale=hist_x, marks=[hist])
br_intsel.observe(brush_callback, names=['selected'])
br_intsel.observe(brush_callback, names=['brushing'])
db3 = Label(color='Black', font_size='24px')
db3.value = str(br_intsel.selected)
display(db3)
h_xax = Axis(scale=hist_x, label='Returns', grids='off', set_ticks=True, tick_format='0.2%')
h_yax = Axis(scale=hist_y, label='Freq', orientation='vertical', grids='off')
fig_hist = Figure(marks=[hist], axes=[h_xax, h_yax], title='Histogram Selection Example', interaction=br_intsel)
display(fig_hist)
In [ ]:
def multi_sel_callback(change):
if(not multi_sel.brushing):
db4.value = str(multi_sel.selected)
In [ ]:
line_x = LinearScale()
line_y = LinearScale()
line = Lines(x=np.arange(100), y=np.random.randn(100), scales={'x': line_x, 'y': line_y})
multi_sel = MultiSelector(scale=line_x, marks=[line])
multi_sel.observe(multi_sel_callback, names=['selected'])
multi_sel.observe(multi_sel_callback, names=['brushing'])
db4 = Label(color='Black', font_size='24px')
db4.value = str(multi_sel.selected)
display(db4)
h_xax = Axis(scale=line_x, label='Returns', grids='off', set_ticks=True)
h_yax = Axis(scale=hist_y, label='Freq', orientation='vertical', grids='off')
fig_multi = Figure(marks=[line], axes=[h_xax, h_yax], title='Multi-Selector Example',
interaction=multi_sel)
display(fig_multi)
In [ ]:
# changing the names of the intervals.
multi_sel.names = ['int1', 'int2', 'int3']
In [ ]:
def multi_sel_dt_callback(change):
if(not multi_sel_dt.brushing):
db_multi_dt.value = str(multi_sel_dt.selected)
In [ ]:
line_dt_x = DateScale(min=np.datetime64(py_dtime(2007, 1, 1)))
line_dt_y = LinearScale()
line_dt = Lines(x=dates_actual, y=sec2_data, scales={'x': line_dt_x, 'y': line_dt_y}, colors=['red'])
multi_sel_dt = MultiSelector(scale=line_dt_x)
multi_sel_dt.observe(multi_sel_dt_callback, names=['selected'])
multi_sel_dt.observe(multi_sel_dt_callback, names=['brushing'])
db_multi_dt = Label(color='Black', font_size='24px')
db_multi_dt.value = str(multi_sel_dt.selected)
display(db_multi_dt)
h_xax_dt = Axis(scale=line_dt_x, label='Returns', grids='off')
h_yax_dt = Axis(scale=line_dt_y, label='Freq', orientation='vertical', grids='off')
fig_multi_dt = Figure(marks=[line_dt], axes=[h_xax_dt, h_yax_dt], title='Multi-Selector with Date Example',
interaction=multi_sel_dt)
display(fig_multi_dt)
In [ ]:
lasso_sel = LassoSelector()
In [ ]:
xs, ys = LinearScale(), LinearScale()
data = np.arange(20)
line_lasso = Lines(x=data, y=data, scales={'x': xs, 'y': ys})
scatter_lasso = Scatter(x=data, y=data, scales={'x': xs, 'y': ys}, colors=['skyblue'])
bar_lasso = Bars(x=data, y=data/2., scales={'x': xs, 'y': ys})
xax_lasso, yax_lasso = Axis(scale=xs, label='X'), Axis(scale=ys, label='Y', orientation='vertical')
fig_lasso = Figure(marks=[scatter_lasso, line_lasso, bar_lasso], axes=[xax_lasso, yax_lasso],
title='Lasso Selector Example', interaction=lasso_sel)
lasso_sel.marks = [scatter_lasso, line_lasso]
display(fig_lasso)
In [ ]:
scatter_lasso.selected, line_lasso.selected
In [ ]:
xs_pz = DateScale(min=np.datetime64(py_dtime(2007, 1, 1)))
ys_pz = LinearScale()
line_pz = Lines(x=dates_actual, y=sec2_data, scales={'x': xs_pz, 'y': ys_pz}, colors=['red'])
panzoom = PanZoom(scales={'x': [xs_pz], 'y': [ys_pz]})
xax = Axis(scale=xs_pz, label='Date', grids='off')
yax = Axis(scale=ys_pz, label='Price', orientation='vertical', grids='off')
fig_pz = Figure(marks=[line_pz], axes=[xax, yax], interaction=panzoom)
display(fig_pz)
In [ ]:
xs_hd = DateScale(min=np.datetime64(py_dtime(2007, 1, 1)))
ys_hd = LinearScale()
line_hd = Lines(x=dates_actual, y=sec2_data, scales={'x': xs_hd, 'y': ys_hd}, colors=['red'])
handdraw = HandDraw(lines=line_hd)
xax = Axis(scale=xs_hd, label='Date', grids='off')
yax = Axis(scale=ys_hd, label='Price', orientation='vertical', grids='off')
fig_hd = Figure(marks=[line_hd], axes=[xax, yax], interaction=handdraw)
display(fig_hd)
In [ ]:
dt_x = DateScale(date_format=date_fmt, min=py_dtime(2007, 1, 1))
lc1_x = LinearScale()
lc2_y = LinearScale()
lc2 = Lines(x=np.linspace(0.0, 10.0, len(prices)), y=prices * 0.25,
scales={'x': lc1_x, 'y': lc2_y},
display_legend=True,
labels=['Security 1'])
lc3 = Lines(x=dates_actual, y=sec2_data,
scales={'x': dt_x, 'y': lc2_y},
colors=['red'],
display_legend=True,
labels=['Security 2'])
lc4 = Lines(x=np.linspace(0.0, 10.0, len(prices)), y=sec2_data * 0.75,
scales={'x': LinearScale(min=5, max=10), 'y': lc2_y},
colors=['green'], display_legend=True,
labels=['Security 2 squared'])
x_ax1 = Axis(label='Date', scale=dt_x)
x_ax2 = Axis(label='Time', scale=lc1_x, side='top')
x_ay2 = Axis(label=(symbol + ' Price'), scale=lc2_y, orientation='vertical', tick_format='0.2f')
fig = Figure(marks=[lc2, lc3, lc4], axes=[x_ax1, x_ax2, x_ay2])
In [ ]:
## declaring the interactions
multi_sel = MultiSelector(scale=dt_x, marks=[lc2, lc3])
br_intsel = BrushIntervalSelector(scale=lc1_x, marks=[lc2, lc3])
index_sel = IndexSelector(scale=dt_x, marks=[lc2, lc3])
int_sel = FastIntervalSelector(scale=dt_x, marks=[lc3, lc2])
hd = HandDraw(lines=lc2)
hd2 = HandDraw(lines=lc3)
pz = PanZoom(scales={'x': [dt_x], 'y': [lc2_y]})
deb = Label(color='Black', font_size='24px')
deb.value = "hello"
In [ ]:
## Call back handler for the interactions
def test_callback(change):
deb.value = str(change['new'])
multi_sel.observe(test_callback, names=['selected'])
br_intsel.observe(test_callback, names=['selected'])
index_sel.observe(test_callback, names=['selected'])
int_sel.observe(test_callback, names=['selected'])
In [ ]:
from collections import OrderedDict
selection_interacts = ToggleButtons(options=OrderedDict([('HandDraw1', hd), ('HandDraw2', hd2), ('PanZoom', pz),
('FastIntervalSelector', int_sel), ('IndexSelector', index_sel),
('BrushIntervalSelector', br_intsel), ('MultiSelector', multi_sel),
('None', None)]))
display(deb)
display(VBox([fig, selection_interacts], align_self="stretch"))
link((selection_interacts, 'value'), (fig, 'interaction'));
In [ ]:
# Set the scales of lc4 to the ones of lc2 and check if panzoom pans the two.
lc4.scales = lc2.scales